#include <QDebug>
#include <QtPlugin>
#include <QMutex>
#include <QSettings>
#include <QDir>
#include <QApplication>
#include "Settings.h"
#include "SettingsView.h"
#include "Theme.h"

namespace Plugins
{

Settings* Settings::_instance = NULL;


Settings* Settings::instance()
{
    static QMutex mutex;
    if (!_instance) {
        mutex.lock();

        if (!_instance){
            _instance = new Settings;
        }

        mutex.unlock();
    }
    return _instance;
}

QString Settings::lastOpenedProject()
{
    QSettings set;
    return set.value("common/lastOpenedProject").toString();
}

void Settings::setLastOpenedProject(const QString & project)
{
    QSettings set;
    set.setValue("common/lastOpenedProject", project);
}

QString Settings::lastUsedWorkspace()
{
    QSettings set;
    return set.value("common/lastUsedWorkspace", QDir::homePath()).toString();
}

void Settings::setLastUsedWorkspace(const QString & workspace)
{
    QSettings set;
    set.setValue("common/lastUsedWorkspace", workspace);
}

QStringList Settings::recentProjects()
{
    QSettings set;
    QStringList projects;
    int count = set.beginReadArray("recent-projects");
    for(int i = 0; i < count; ++i){
        set.setArrayIndex(i);
        projects.append(set.value("recent-projects").toString());
    }
    set.endArray();
    return projects;
}

void Settings::addRecentProjects(const QString & project)
{
    QStringList projects = recentProjects();
    if (projects.contains(project))
        return;

    QSettings set;
    set.beginWriteArray("recent-projects");
    set.setArrayIndex(0);
    set.setValue("recent-projects", project);
    int cnt = 1;
    foreach(QString prj, projects){
        set.setArrayIndex(cnt);
        set.setValue("recent-projects", prj);
        cnt++;
    }
    set.endArray();
}

QFont Settings::font()
{
    QSettings set;
    return set.value("common/font", QApplication::font()).value<QFont>();
}

void Settings::setFont(const QFont& fnt)
{
    QSettings set;
    set.setValue("common/font", fnt);
    emit themeChanged();
}

QFont Settings::monoFont()
{
    QSettings set;
    return set.value("common/monofont", QApplication::font()).value<QFont>();
}

void Settings::setMonoFont(const QFont& fnt)
{
    QSettings set;
    set.setValue("common/monofont", fnt);
}

void Settings::showPreferences(QWidget * parent)
{
    SettingsView set(parent);
    set.exec();
}

QList<QString> Settings::themesList()
{
    QList<QString> list;
    foreach(QFileInfo theme, _themesPath.entryList(QDir::Files)){
        list << theme.baseName();
    }

    return list;
}

QString Settings::currentThemeName()
{
    QSettings set;
    return set.value("common/current-theme", "default").toString();
}

void Settings::setCurrentThemeName(const QString& themeName)
{
    QSettings set;
    return set.setValue("common/current-theme", themeName);
}

ITheme * Settings::currentTheme()
{
    return themeByName(currentThemeName());
}

ITheme * Settings::fallbackTheme()
{
    return new Theme("", this);
}

ITheme * Settings::themeByName(const QString & themeName)
{
    if (!_themes.contains(themeName)){
        QString path = _themesPath.absolutePath()+QDir::separator()+themeName+".conf";
        if (QFile::exists(path))
            _themes.insert(themeName, new Theme(path, this));
        else return NULL;
    }
    return _themes[themeName];
}

Settings::Settings():
    QObject()
{
    QSettings set;
    QSettings cfg(QSettings::IniFormat, QSettings::UserScope, set.organizationName(), set.applicationName());
    QDir configDir(QFileInfo(cfg.fileName()).absolutePath() + QDir::separator()+"themes");
    if (!configDir.exists())
        configDir.mkdir(configDir.absolutePath());
    _themesPath = configDir.absolutePath();
    connect(QApplication::instance(), SIGNAL(aboutToQuit()), SLOT(closeSettings()));
}

Settings::~Settings()
{
    qDeleteAll(_themes);
}

void Settings::closeSettings()
{
    delete _instance;
}

void Settings::setThemeChanged()
{
    emit themeChanged();
}

IEditors::EditorType Settings::getTypeByExtension(const QString & fileName)
{
    QString ext = fileName.split(".").last();

    QSettings set;
    if (set.value("editors/python-extensions", "py;py2;py3").toString().split(";").contains(ext))
        return IEditors::Python;
    if (set.value("editors/qrc-extensions", "qrc").toString().split(";").contains(ext))
        return IEditors::QRC;
    if (set.value("editors/xml-extensions", "xml").toString().split(";").contains(ext))
        return IEditors::XML;
    if (set.value("editors/qml-extensions", "qml").toString().split(";").contains(ext))
        return IEditors::QML;
    if (set.value("editors/ui-extensions", "ui").toString().split(";").contains(ext))
        return IEditors::UI;
    if (set.value("editors/jinja-extensions", "tmpl;thtml").toString().split(";").contains(ext))
        return IEditors::Jinja;
    return IEditors::Text;
}

bool Settings::restoreProject()
{
    QSettings set;
    return set.value("common/restore-project", true).toBool();
}

void Settings::setRestoreProject(bool restore)
{
    QSettings set;
    return set.setValue("common/restore-project", restore);
}

bool Settings::restoreFiles()
{
    QSettings set;
    return set.value("common/restore-project", true).toBool() && set.value("common/restore-files", true).toBool();
}

void Settings::setRestoreFiles(bool restore)
{
    QSettings set;
    return set.setValue("common/restore-files", restore);
}

QString Settings::py3()
{
    QSettings set;
    QString path = set.value("common/py3", "").toString();
    if (path == ""){
#ifdef Q_OS_WIN
        path = "python3.exe";
#else
        path = "python3";
#endif
    }
    return path;
}

QString Settings::py2()
{
    QSettings set;
    QString path = set.value("common/py2", "").toString();
    if (path == ""){
#ifdef Q_OS_WIN
        path = "python2.exe";
#else
        path = "python2";
#endif
    }
    return path;
}

void Settings::setPy3(const QString & path)
{
    QSettings set;
    set.setValue("common/py3", path);
}

void Settings::setPy2(const QString & path)
{
    QSettings set;
    set.setValue("common/py2", path);
}

QString Settings::pyuic4()
{
    QSettings set;
    return set.value("common/pyuic4", "pyuic4").toString();
}

void Settings::setPyuic4(const QString & path)
{
    QSettings set;
    set.setValue("common/pyuic4", path);
}

QString Settings::themesPath()
{
    return _themesPath.path();
}

}
